package com.small.nine.watch.dog.service.impl;

import cn.hutool.core.util.StrUtil;
import com.small.nine.watch.dog.common.lock.WatchDogLock;
import com.small.nine.watch.dog.service.WatchDogTestService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author sheng_zs@126.com
 * @date 2021-07-26 9:24
 */
@Slf4j
@Service
public class WatchDogTestServiceImpl implements WatchDogTestService {
    @Resource
    private ValueOperations<String, Object> valueOperations;

    @Override
    public String getAccessToken() {
        final String key = "access_token:appId";
        /*
            1. 先获取 redis 上的 token
         */
        Object o = valueOperations.get(key);
        String token = "";
        if (Objects.nonNull(o) && StrUtil.isNotBlank(token = o.toString())) {
            return token;
        }
        // 获取看门狗锁
        WatchDogLock lock = new WatchDogLock(key + ":lock");
//        lock.lock();
        if (lock.tryLock(30, TimeUnit.SECONDS)) {
            try {
                // 休眠测试
                log.info("开始休眠");
                TimeUnit.MINUTES.sleep(1);

                // 防止不是第一个拿到锁
                o = valueOperations.get(key);
                if (Objects.nonNull(o) && StrUtil.isNotBlank(token = o.toString())) {
                    return token;
                }
                // 获取 access_token
                token = "获取逻辑。。。";

                log.info("获取 token 成功：{}", token);
                // 设置到 redis
                valueOperations.set(key, token, 2, TimeUnit.HOURS);

            } catch (Exception e) {
                log.error("获取 access_token 失败");
            } finally {
                lock.unlock();
            }
        } else {
            log.info("获取锁失败！");
        }
        return token;
    }
}
